package com.jiang.thread.apply;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 需要等待结果
 */
@Slf4j
public class WaitRes {
    static int res = 1;

    /**
     * join 实现（同步）
     *  需要外部共享变量，不符合面向对象封装的思想
     *  必须等待线程结束，不能配合线程池使用
     */
    @Test
    public void test1() throws InterruptedException {
        log.info(Thread.currentThread().getName() + "开始");
        Thread t1 = new Thread(()->{
            log.info(Thread.currentThread().getName() + "开始");
            try {
                Thread.sleep(2000);
                res = 10;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info(Thread.currentThread().getName() + "结束");
        }, "t1");
        t1.start();
//        t1.run();   //直接调用run方法，程序中依然只有主线程这一个线程
        t1.join();
        log.info(Thread.currentThread().getName() + "结束，结果为：{}", res);
    }

    /**
     * Future 实现（同步）
     *  规避了使用 join 之前的缺点
     *  可以方便配合线程池使用
     */
    @Test
    public void test2() throws InterruptedException, ExecutionException {
        log.info(Thread.currentThread().getName() + "开始");
        FutureTask<Integer> ft = new FutureTask(()->{
            log.info(Thread.currentThread().getName() + "开始");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info(Thread.currentThread().getName() + "结束");
            return 10;
        });
        new Thread(ft, "t1").start();
        // get 方法是让调用线程同步等待
        log.info(Thread.currentThread().getName() + "结束，结果为：{}", ft.get());
    }
}
